package com.it.zk;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.api.CuratorEvent;
import org.apache.curator.framework.api.CuratorListener;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.data.Stat;

import java.util.List;

/**
 * @author co
 */
@Slf4j
public class Test01 {
    public static void main(String[] args) throws Exception {
        /* 参数名	说明
        connectionString	服务器列表，格式host1:port1,host2:port2,…
        retryPolicy	重试策略,内建有四种重试策略,也可以自行实现RetryPolicy接口
        sessionTimeoutMs	会话超时时间，单位毫秒，默认60000ms
        connectionTimeoutMs	连接创建超时时间，单位毫秒，默认60000ms
        */
//        RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
//        CuratorFramework client =
//                CuratorFrameworkFactory.newClient(
//                        "127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183",
//                        5000,
//                        3000,
//                        retryPolicy);

        RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
        CuratorFramework client = CuratorFrameworkFactory.builder()
                .connectString("127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183")
                .sessionTimeoutMs(5000)
                .connectionTimeoutMs(5000)
                .namespace("base")
                .retryPolicy(retryPolicy)
                .build();
        client.start();
//        client.create().forPath("path","init".getBytes());
//        client.create().creatingParentsIfNeeded().forPath("/parent/chlib/path");
//        client.create().creatingParentContainersIfNeeded().forPath("/parent/chlib/path");
//        这个creatingParentContainersIfNeeded()接口非常有用，因为一般情况开发人员在创建一个子节点必须判断它的父节点是否存在，如果不存在直接创建会抛出NoNodeException，使用creatingParentContainersIfNeeded()之后Curator能够自动递归创建所有所需的父节点。
//        client.create().withMode(CreateMode.EPHEMERAL).forPath("path","init".getBytes());
//        Zookeeper的节点创建模式：
//        PERSISTENT：持久化
//        PERSISTENT_SEQUENTIAL：持久化并且带序列号
//        EPHEMERAL：临时
//        EPHEMERAL_SEQUENTIAL：临时并且带序列号

//        client.delete().deletingChildrenIfNeeded().forPath("path");

//        client.delete().guaranteed().forPath("/parent");
        /**
         * 删除一个节点，并且递归删除其所有的子节点
         */
//        client.delete().deletingChildrenIfNeeded().forPath("/parent");
        /**
         * 只可以删除页子节点，
         */
//        client.delete().forPath("path");
        /**
         * guaranteed()接口是一个保障措施，只要客户端会话有效，那么Curator会在后台持续进行删除操作，直到删除节点成功。
         */
//        byte[] data= client.getData().forPath("/hello");
//        String st=new String(data);
//        System.out.println(st);
//        Stat stat = new Stat();
//        byte[] data=  client.getData().storingStatIn(stat).forPath("/hello");
//        String st=new String(data);
//        log.info(JSON.toJSONString(stat));
//
//        stat=client.setData().forPath("/hello","data".getBytes());
//
//        List<String> childPathList=client.getChildren().forPath("/hello");
//        log.info(JSON.toJSONString(childPathList));


        //创建监听器
        CuratorListener listener = new CuratorListener() {

            @Override
            public void eventReceived(CuratorFramework client, CuratorEvent event)
                    throws Exception {
                log.info(JSON.toJSONString(event));
                System.out.println(event.getPath());
            }
        };

        //添加监听器
        client.getCuratorListenable().addListener(listener);

        //异步设置某个节点数据
//        client.create().forPath("/curator","/curator modified data with Async".getBytes());

        byte[] curator=client.getData().forPath("/curator");
        log.info(JSON.toJSONString(new String(curator)));
        //为了防止单元测试结束从而看不到异步执行结果，因此暂停10秒
        Thread.sleep(1000000);


    }

    /**
     * 测试异步设置节点数据
     * @throws Exception
     */
    public void testSetDataAsync() throws Exception{
        RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
        CuratorFramework client = CuratorFrameworkFactory.builder()
                .connectString("127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183")
                .sessionTimeoutMs(5000)
                .connectionTimeoutMs(5000)
                .namespace("base")
                .retryPolicy(retryPolicy)
                .build();
        client.start();
        //创建监听器
        CuratorListener listener = new CuratorListener() {

            @Override
            public void eventReceived(CuratorFramework client, CuratorEvent event)
                    throws Exception {
                System.out.println(event.getPath());
            }
        };

        //添加监听器
        client.getCuratorListenable().addListener(listener);

        //异步设置某个节点数据
//        client.setData().inBackground().forPath("/curator","/curator modified data with Async".getBytes());

        //为了防止单元测试结束从而看不到异步执行结果，因此暂停10秒
        Thread.sleep(10000);
    }

}
